<?php
/* SVN FILE: $Id: app_controller.php 20 2009-05-02 13:50:00Z ake.svedin $ */
/**
 * Travian Alliance Coordinator
 * Copyright (c) 2009 Åke Svedin.
 *
 * This file is part of Travian Alliance Coordinator.
 *
 * Travian Alliance Coordinator is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Travian Alliance Coordinator is distributed in the hope that it will be
 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * Travian Alliance Coordinator.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author $Author: ake.svedin $
 * @copyright Copyright (c) 2009 Åke Svedin.
 * @version $Revision: 20 $
 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3
 */
class AppController extends Controller {

    var $uses = array('Setting');
    var $components = array('Auth', 'RememberMe');

    function whitespace(&$value, &$key){
        $key = trim($key);
        $value = trim($value);
    }

    function beforeFilter(){
        // set the default highlighted menu item
        $this->set('Menu_active', 'start');

        //reads the site-wide config values from the DB and puts them through the Configure::write method
        $this->Setting->getcfg();
        //trim all posted data
        if(!empty($this->data)) array_walk_recursive($this->data, array($this, 'whitespace'));

        //Set application wide actions which do not require authentication
        $this->Auth->allow(array('register', 'login', 'logout'));
        //Set the default redirect for users who logout
        $this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'login', 'admin' => false);
        //Set the default redirect for users who login
        $this->Auth->loginRedirect = array('controller' => '/', 'admin' => false);
        //Extend auth component to include authorisation via isAuthorized action
        $this->Auth->authorize = 'controller';
        //Restrict access to only users with an active account
        $this->Auth->userScope = array('User.active = 1');
        $this->Auth->autoRedirect = false;
        //Pass auth component data over to view files
        $this->set('Auth', $this->Auth->user());
        
        //Check for saved cookie
        $this->RememberMe->check();
    }

    function beforeRender(){
        //If we have an authorised user logged then pass over an array of controllers
        //to which they have index action permission
        if($this->Auth->user()){
            $controllerList = Configure::listObjects('controller');
            $permittedControllers = array();
            foreach($controllerList as $controllerItem){
                if($controllerItem <> 'App'){
                    if($this->__permitted($controllerItem, 'index')){
                        $permittedControllers[] = $controllerItem;
                    }
                }
            }
        }
        $this->set(compact('permittedControllers'));
    }


    /**
     * isAuthorized
     *
     * Called by Auth component for establishing whether the current authenticated
     * user has authorization to access the current controller:action
     *
     * @return true if authorised/false if not authorized
     * @access public
     */
    function isAuthorized(){
        return $this->__permitted($this->name, $this->action);
    }


    /**
     * __permitted
     *
     * Helper function returns true if the currently authenticated user has permission
     * to access the controller:action specified by $controllerName:$actionName
     * @return
     * @param $controllerName Object
     * @param $actionName Object
     */
    function __permitted($controllerName, $actionName){
        //Ensure checks are all made lower case
        $controllerName = low($controllerName);
        $actionName = low($actionName);
        //If permissions have not been cached to session...
        if(!$this->Session->check('Permissions')){
            //...then build permissions array and cache it
            $permissions = array();
            //everyone gets permission to logout
            $permissions[] = 'users:logout';
            //Import the User Model so we can build up the permission cache
            App::import('Model', 'User');
            $thisUser = new User;
            //Now bring in the current users full record along with groups
            $thisGroups = $thisUser->find(array('User.id' => $this->Auth->user('id')));
            $thisGroups = $thisGroups['Group'];
          
            foreach($thisGroups as $thisGroup){
                $thisPermissions = $thisUser->Group->find(array('Group.id' => $thisGroup['id']));
                $thisPermissions = $thisPermissions['Permission'];
                foreach($thisPermissions as $thisPermission){
                    $permissions[] = $thisPermission['name'];
                }
            }
            //write the permissions array to session
            $this->Session->write('Permissions', $permissions);
        }else{
            //...they have been cached already, so retrieve them
            $permissions = $this->Session->read('Permissions');
        }
        //Now iterate through permissions for a positive match
        foreach($permissions as $permission){
            if($permission == '*'){
                return true;//Super Admin Bypass Found
            }
            if($permission == $controllerName.':*'){
                return true;//Controller Wide Bypass Found
            }
            if($permission == $controllerName.':'.$actionName){
                return true;//Specific permission found
            }
        }
        return false;
    }
}
?>